package cn.blank.calc;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.RepeatedTest;

/**
 * 进制计算
 * <br/>Date 2022/4/1
 * <br/>Time 16:31:41
 *
 * @author _blank
 */
public class BaseCalculator {

    /*
     * 进制转换器
     * https://www.iamwawa.cn/jinzhi.html
     *
     * 在线进制转换
     * https://tool.oschina.net/hexconvert/
     */

    @RepeatedTest(3)
    @DisplayName("十进制转二进制")
    void decimalToBinary() {
        // 十进制数据
        final int val = RandomUtils.nextInt(0, 99);

        int result = val;
        int remainder;
        int cycles = 0;
        final StringBuilder binaryResult = new StringBuilder();
        do {
            if (cycles == 0) {
                System.out.printf("2 \uD840\uDCCA %d\n", result);
            }

            remainder = result % 2;
            binaryResult.append(remainder);
            result = result / 2;

            System.out.printf(StringUtils.leftPad("", ++cycles) + (result == 0 ? "    " : "2 \uD840\uDCCA") + " %d    余 %d\n", result, remainder);
        } while (result != 0);

        // jdk自带二进制转十进制 radix表示原值是几进制
        // Integer.parseInt(binaryResult.reverse().toString(), 2);

        System.out.printf("十进制 %d 转换二进制的结果是：%s\n\n", val, binaryResult.reverse().toString());
    }

    @RepeatedTest(3)
    @DisplayName("二进制转十进制")
    void binaryToDecimal() {
        // bug 这么定义有问题的
        final char[] superscript = {'º', '¹', '²', '³', '⁴', '⁵', '⁶', '⁷', '⁸', '⁹'};

        // 采用权相加法
        final int val = RandomUtils.nextInt(0, 99);
        // jdk自带十进制转二进制
        final String binaryStr = Integer.toBinaryString(val);
        final int binaryStrLen = binaryStr.length();
        final StringBuilder decimal = new StringBuilder();
        for (int i = 0; i < binaryStrLen; i++) {
            final char charAt = binaryStr.charAt(i);
            final int parseInt = Integer.parseInt(String.valueOf(charAt));
            final int power = binaryStrLen - i - 1;
            final int currentCalculatedValue = parseInt * (int) Math.pow(2, power);
            decimal.append(i == 0 ? "" : " + ")
                    .append(parseInt).append("×").append(2).append(superscript[power])
                    .append(" (").append(currentCalculatedValue).append(")");
        }
        System.out.println("二进制：" + binaryStr + " 转十进制：" + val + "\n过程：" + decimal.toString() + " = " + val + "\n");
    }

}
